import { getREM } from './common.js'
// 定义一个 canvas 工具类
export default class CanvasUtils {
  // 创建 canvas 对象 和context 对象
  static createCanvas (width, height, display = "none") {
    const canvas = document.createElement('canvas');
    canvas.style.display = display
    canvas.width = getREM(width);
    canvas.height = getREM(height);
    return canvas;
  }

  // 绘制一个矩形
  static drawRect (context, x, y, width, height, color) {
    context.fillStyle = color;
    context.fillRect(getREM(x), getREM(y), getREM(width), getREM(height));
  }
  // 绘制一个图片
  static drawImg (context, image, x, y, w, h) {
    return new Promise((resolve, reject) => {
      this.loadImg(image).then(res => {
        context.drawImage(res, getREM(x), getREM(y), getREM(w), getREM(h));
        resolve()
      }).catch(err => {
        reject(err)
      })
    }).catch((e) => {
      console.log("%c 行数：-28-「canvasUtils」", "font-size:14px; background:#2ACC99; color:#ffffff;", e);
    })
  }
  static loadImg (link) {
    return new Promise((resolve, reject) => {
      const img = new Image()
      img.crossOrigin = 'Anonymous'
      img.src = link
      img.onload = () => {
        resolve(img)
      }
      img.onerror = (err) => {
        reject(err)
      }
    }).catch((e) => { })
  }
  /**
   * 绘制圆角矩形
   * @param {Object} context - canvas组件的绘图上下文
   * @param {Number} x - 矩形的x坐标
   * @param {Number} y - 矩形的y坐标
   * @param {Number} w - 矩形的宽度
   * @param {Number} h - 矩形的高度
   * @param {Number} r - 矩形的圆角半径
   * @param {String} [c = 'transparent'] - 矩形的填充色
   */
  static drawRoundRect (context, x, y, w, h, r, background = 'transparent') {
    if (w < 2 * r) {
      r = w / 2
    }
    if (h < 2 * r) {
      r = h / 2
    }

    context.beginPath()
    context.fillStyle = background

    context.arc(getREM(x + r), getREM(y + r), getREM(r), Math.PI, Math.PI * 1.5)
    context.moveTo(getREM(x + r), getREM(y))
    context.lineTo(getREM(x + w - r), getREM(y))
    context.lineTo(getREM(x + w), getREM(y + r))

    context.arc(getREM(x + w - r), getREM(y + r, r), Math.PI * 1.5, Math.PI * 2)
    context.lineTo(getREM(x + w), getREM(y + h - r))
    context.lineTo(getREM(x + w - r), getREM(y + h))

    context.arc(getREM(x + w - r), getREM(y + h - r), getREM(r), 0, Math.PI * 0.5)
    context.lineTo(getREM(x + r), getREM(y + h))
    context.lineTo(x, y + h - r)

    context.arc(getREM(x + r), getREM(y + h - r), getREM(r), Math.PI * 0.5, Math.PI)
    context.lineTo(getREM(x), getREM(y + r))
    context.lineTo(getREM(x) + getREM(r, y))

    context.fill()
    context.closePath()
  }

  /**
   * @description: 绘制圆形图+图片
   * @param {*} canvas
   * @param {*} img 图片路径
   * @param {*} x 左上角X轴坐标
   * @param {*} y 左上角y轴坐标
   * @param {*} r 圆弧半径
   * @param {*} w 图片宽度
   * @param {*} h 图片高度
   * @param {*} borderWidth 边框宽度
   * @param {*} borderColor 边框颜色
   * @return {*}
   */
  static drawArcImage (context, img, x, y, r, borderWidth = 0, w, h, borderColor = 'transparent') {
    return new Promise((resolve, reject) => {
      this.loadImg(img).then(res => {
        /*先保存状态*/
        context.save()
        context.beginPath()
        const circleX = getREM(x + r + borderWidth)
        const circleY = getREM(y + r + borderWidth)
        const circleR = getREM(r + borderWidth)
        if (borderWidth !== 0) {
          context.arc(circleX, circleY, circleR, 0, 2 * Math.PI)
          context.fillStyle = borderColor
          context.fill()
          context.beginPath()
        }
        context.arc(circleX, circleY, getREM(r), 0, 2 * Math.PI)
        //画裁剪区域，此处以圆为例
        context.clip()
        context.drawImage(res, getREM(x + borderWidth), getREM(y + borderWidth), getREM(w), getREM(h))
        /*裁剪后恢复到save()保存的状态*/
        context.restore()
        context.closePath()
        resolve()
      }).catch(err => {
        reject(err)
      })
    }).catch((e) => {
      console.log("%c 行数：-124-「canvasUtils」", "font-size:14px; background:#2ACC99; color:#ffffff;", e);
    })
  }

  // 绘制一个文本
  static drawText (context, text = '', x = 0, y = 0, style) {
    const {
      font = '',
      textBaseline = 'middle',
      textAlign = 'left',
      fillStyle = '#333333',
    } = style
    // 设置字体大小
    context.font = font
    // 更改字号后，必须重置对齐方式，否则居中麻烦。设置文本的垂直对齐方式
    context.textBaseline = textBaseline
    context.textAlign = textAlign
    // 文字颜色
    context.fillStyle = fillStyle
    // 文字在画布的位置
    context.fillText(text, getREM(x), getREM(y))
  }
  // 文本追加事件
  static onTextAppend (context, parentText, text, x, y, style) {
    const {
      font = '',
      textBaseline = 'middle',
      textAlign = 'left',
      fillStyle = '#333333',
    } = style

    // 获取文本的宽度
    const textWidth = context.measureText(parentText).width;
    // 将光标移动到指定位置
    context.translate(textWidth, 0);
    context.font = font
    // 更改字号后，必须重置对齐方式，否则居中麻烦。设置文本的垂直对齐方式
    context.textBaseline = textBaseline
    context.textAlign = textAlign
    // 文字颜色
    context.fillStyle = fillStyle
    // 追加文本
    context.fillText(text, getREM(x), getREM(y));
    // 清除光标
    context.translate(-textWidth, 0);
  }
  /**
   * @description: 绘制换行文本
   * @param {*} context
   * @param {*} text
   * @param {*} left
   * @param {*} top
   * @param {*} w
   * @param {*} style
   * @return {*}
   */
  static drawLineFeedText (context, text = '', left = 0, top = 0, w, style) {
    context.save()
    context.beginPath()
    const {
      font = '',
      textBaseline = 'middle',
      textAlign = 'left',
      fillStyle = '#333333',
    } = style
    const row = []
    let temp = ''
    context.font = font
    context.fillStyle = fillStyle
    context.textBaseline = textBaseline
    context.textAlign = textAlign

    text.split('').forEach((val) => {
      if (context.measureText(temp).width > w) {
        row.push(temp)
        temp = ''
      }
      temp += val
    })
    /*最后把剩余没达到w的push进去*/
    row.push(temp)
    row.forEach((val, index) => {
      context.fillText(val, Base.WIDTH - left, top + index * 30)
    })
  }

  /**
   * @description: 图片格式输入
   * @param {*} base64 图片
   * @return {*}
   */
  static base64ToBlob (base64) {
    const arr = base64.split(',')
    const mime = arr[0].match(/:(.*?);/)[1]
    const bStr = atob(arr[1]) //解码的字符串
    let n = bStr.length
    const u8Arr = new Uint8Array(n) //TypedArray视图
    while (n--) {
      /*给视图分配内存；charCodeAt() 方法可返回指定位置的字符的 Unicode 编码。这个返回值是 0 - 65535 之间的整数。
       * 因为这里返回的都是0到255的编码，所以用无符号8位表示
       * */
      u8Arr[n] = bStr.charCodeAt(n)
    }
    return new Blob([u8Arr], {
      type: mime,
    })
  }

  // 生成图片
  static generateImage (canvas) {
    const base64 = canvas.toDataURL('image/jpg')
    const blob = this.base64ToBlob(base64)
    return { base64, blob };
  }
}
